package com.leyou.common.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sun.istack.internal.Nullable;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.List;
import java.util.Map;

public class JsonUtils {

	public static final ObjectMapper mapper = new ObjectMapper();

	private static final Logger logger = LoggerFactory.getLogger(JsonUtils.class);

	@Nullable
	public static String serialize(Object obj) {
		if (obj == null) {
			return null;
		}
		if (obj.getClass() == String.class) {
			return (String) obj;
		}
		try {
			return mapper.writeValueAsString(obj);
		} catch (JsonProcessingException e) {
			logger.error("json序列化出错：" + obj, e);
			return null;
		}
	}
	@Nullable
	public static String toString(Object obj) {
		if (obj == null) {
			return null;
		}
		if (obj.getClass() == String.class) {
			return (String) obj;
		}
		try {
			return mapper.writeValueAsString(obj);
		} catch (JsonProcessingException e) {
			logger.error("json序列化出错：" + obj, e);
			return null;
		}
	}

	@Nullable
	public static <T> T parse(String json, Class<T> tClass) {
		try {
			return mapper.readValue(json, tClass);
		} catch (IOException e) {
			logger.error("json解析出错：" + json, e);
			return null;
		}
	}
	@Nullable
	public static <T> T toBean(String json, Class<T> tClass) {
		try {
			return mapper.readValue(json, tClass);
		} catch (IOException e) {
			logger.error("json解析出错：" + json, e);
			return null;
		}
	}
	@Nullable
	public static <E> List<E> parseList(String json, Class<E> eClass) {
		try {
			return mapper.readValue(json, mapper.getTypeFactory().constructCollectionType(List.class, eClass));
		} catch (IOException e) {
			logger.error("json解析出错：" + json, e);
			return null;
		}
	}
	@Nullable
	public static <E> List<E> toList(String json, Class<E> eClass) {
		try {
			return mapper.readValue(json, mapper.getTypeFactory().constructCollectionType(List.class, eClass));
		} catch (IOException e) {
			logger.error("json解析出错：" + json, e);
			return null;
		}
	}

	@Nullable
	public static <K, V> Map<K, V> parseMap(String json, Class<K> kClass, Class<V> vClass) {
		try {
			return mapper.readValue(json, mapper.getTypeFactory().constructMapType(Map.class, kClass, vClass));
		} catch (IOException e) {
			logger.error("json解析出错：" + json, e);
			return null;
		}
	}
	@Nullable
	public static <K, V> Map<K, V> toMap(String json, Class<K> kClass, Class<V> vClass) {
		try {
			return mapper.readValue(json, mapper.getTypeFactory().constructMapType(Map.class, kClass, vClass));
		} catch (IOException e) {
			logger.error("json解析出错：" + json, e);
			return null;
		}
	}
	@Nullable
	public static <T> T nativeRead(String json, TypeReference<T> type) {
		try {
			return mapper.readValue(json, type);
		} catch (IOException e) {
			logger.error("json解析出错：" + json, e);
			return null;
		}
	}

//	public static void main(String[] args) {
//		User user = new User("Jack",21);
//		//序列化
//		String struser = toString(user);
//		System.out.println(struser);
//		//反序列化
//
//		User usertobean = toBean(struser,User.class);
//		System.out.println(usertobean);
//
//		//toList
//		String json = "[20 , -10 , 5 , 15]";
//
//		List<Integer> list = toList(json,Integer.class);
//		System.out.println("list:"+list);
//
//		//toMap
//		String json2 = "{\"name\": \"Jack\",\"age\": \"21\"}";
//
//		Map<String,String> map =  toMap(json2,String.class,String.class);
//
//		System.out.println("Map:"+map);
//		System.out.println("===============================");
//		String json3 = "[{\"name\": \"Jack\",\"age\": \"21\"},{\"name\": \"zhangsan\",\"age\": \"18\"}]";
//
//		List<Map<String,String>> maps = nativeRead(json3, new TypeReference<List<Map<String,String>>>() {});
//
//		for (Map<String, String> stringStringMap : maps) {
//
//			System.out.println("stringStringMap:"+stringStringMap);
//
//		}
//
//	}

}